home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
aminet
/
util
/
edit
/
jed207.lha
/
src
/
jed.lha
/
render.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-09-18
|
14KB
|
554 lines
/*
* RENDER.C
* (c) 1992 J.Harper
*/
#include "jed.h"
#include "jed_protos.h"
#define TEXTPEN 1
#define BLOCKPEN 2
#define CURSPEN 3
Prototype VOID pentocursor (VOID);
Prototype VOID pentoline (WORD);
Prototype VOID pentopos (WORD, WORD);
Prototype VOID setpospen (WORD, LONG);
Prototype VOID cursor (BOOL);
Local VOID drawbit (STRPTR, WORD, WORD);
Prototype VOID drawline (LINE *, LONG);
Prototype VOID drawlinepart (LINE *, LONG, WORD);
Prototype VOID redrawall (VOID);
Prototype VOID redrawallfrom (WORD, LONG);
Prototype VOID redrawline (LONG);
Prototype VOID redrawlinefrom (WORD, LONG);
Prototype VOID redrawcmdline (STRPTR, STRPTR, LONG, LONG);
Prototype VOID redrawcmdlinefrom(STRPTR, STRPTR, LONG, LONG, WORD);
Prototype VOID restorecmdline (VOID);
Prototype VOID cmdlncursor (BOOL);
Prototype VOID refresh (VOID);
Prototype VOID setrefresh (WORD, WORD, LONG);
Prototype VOID refreshallviews (TX *);
VOID
pentocursor(VOID)
{
VW *vw = CurrVW;
Move(vw->vw_Rp, vw->vw_XStartPix + ((vw->vw_CursorPos.pos_Col - vw->vw_StartCol) * vw->vw_FontX), vw->vw_FontStart + ((vw->vw_CursorPos.pos_Line - vw->vw_StartLine) * vw->vw_FontY));
}
/*
* note actual y coordinate not line number
*/
VOID
pentoline(WORD yPos)
{
VW *vw = CurrVW;
Move(vw->vw_Rp, vw->vw_XStartPix, vw->vw_FontStart + (yPos * vw->vw_FontY));
}
/*
* this also takes coordinates...
*/
VOID
pentopos(WORD xPos, WORD yPos)
{
VW *vw = CurrVW;
Move(vw->vw_Rp, vw->vw_XStartPix + (xPos * vw->vw_FontX), vw->vw_FontStart + (yPos * vw->vw_FontY));
}
/*
* ...but this wants column and line numbers (confusing, eh?)
*/
VOID
setpospen(WORD col, LONG line)
{
if(posinblock(col, line))
SetAPen(CurrVW->vw_Rp, BLOCKPEN);
else
SetAPen(CurrVW->vw_Rp, TEXTPEN);
SetDrMd(CurrVW->vw_Rp, JAM2);
}
VOID
cursor(BOOL status)
{
VW *vw = CurrVW;
if((!vw->vw_Sleeping) && (!vw->vw_DisplayLock))
{
LINE *line = vw->vw_Tx->tx_Lines + vw->vw_CursorPos.pos_Line;
WORD cursoff = vw->vw_CursorPos.pos_Col;
struct RastPort *rp = vw->vw_Rp;
if(status)
{
SetAPen(rp, CURSPEN);
SetDrMd(rp, JAM1 | INVERSVID);
}
else if(cursinblock())
{
SetAPen(rp, BLOCKPEN);
SetDrMd(rp, JAM2);
}
else
{
SetAPen(rp, TEXTPEN);
SetDrMd(rp, JAM2);
}
pentocursor();
if((cursoff + 1) >= line->ln_Strlen)
Text(rp, " ", 1);
else
Text(rp, line->ln_Line + cursoff, 1);
}
}
/*
* draws a section of a line of text, beg and end are x ordinates
*/
Local VOID
drawbit(STRPTR str, WORD beg, WORD end)
{
VW *vw = CurrVW;
WORD startx = vw->vw_StartCol;
WORD endx = vw->vw_MaxX + startx + 1;
if(end > startx)
{
WORD length;
if(beg < startx)
beg = startx;
if(end > endx)
end = endx;
if((length = end - beg - 1) > 0)
Text(vw->vw_Rp, str + beg, length);
}
}
/*
* pen should be at start of line to draw (line should be cleared first)
*/
VOID
drawline(LINE *line, LONG lineNum)
{
VW *vw = CurrVW;
struct RastPort *rp = vw->vw_Rp;
if(vw->vw_BlockStatus)
{
SetAPen(rp, TEXTPEN);
SetDrMd(rp, JAM2);
drawbit(line->ln_Line, 0, line->ln_Strlen);
}
else
{
WORD flag = lineinblock(lineNum);
switch(flag)
{
case 0: /* none of line in block */
SetAPen(rp, TEXTPEN);
SetDrMd(rp, JAM2);
drawbit(line->ln_Line, 0, line->ln_Strlen);
break;
case 1: /* whole of line in block */
SetAPen(rp, BLOCKPEN);
SetDrMd(rp, JAM2);
drawbit(line->ln_Line, 0, line->ln_Strlen);
break;
case 2: /* start of line in block */
SetAPen(rp, BLOCKPEN);
SetDrMd(rp, JAM2);
drawbit(line->ln_Line, 0, vw->vw_Block[1].pos_Col + 1);
SetAPen(rp, TEXTPEN);
drawbit(line->ln_Line, vw->vw_Block[1].pos_Col, line->ln_Strlen);
break;
case 3: /* end of line in block */
SetAPen(rp, TEXTPEN);
SetDrMd(rp, JAM2);
drawbit(line->ln_Line, 0, vw->vw_Block[0].pos_Col + 1);
SetAPen(rp, BLOCKPEN);
drawbit(line->ln_Line, vw->vw_Block[0].pos_Col, line->ln_Strlen);
break;
case 4: /* middle of line in block */
SetAPen(rp, TEXTPEN);
SetDrMd(rp, JAM2);
drawbit(line->ln_Line, 0, vw->vw_Block[0].pos_Col + 1);
SetAPen(rp, BLOCKPEN);
drawbit(line->ln_Line, vw->vw_Block[0].pos_Col, vw->vw_Block[1].pos_Col + 1);
SetAPen(rp, TEXTPEN);
drawbit(line->ln_Line, vw->vw_Block[1].pos_Col, line->ln_Strlen);
break;
}
}
}
/*
* pen should be at first draw position
*/
VOID
drawlinepart(LINE *line, LONG lineNum, WORD xStart)
{
VW *vw = CurrVW;
struct RastPort *rp = vw->vw_Rp;
if(vw->vw_BlockStatus)
{
SetAPen(rp, TEXTPEN);
SetDrMd(rp, JAM2);
drawbit(line->ln_Line, xStart, line->ln_Strlen);
}
else
{
WORD flag = lineinblock(lineNum);
switch(flag)
{
case 0: /* none of line in block */
SetAPen(rp, TEXTPEN);
SetDrMd(rp, JAM2);
drawbit(line->ln_Line, xStart, line->ln_Strlen);
break;
case 1: /* whole of line in block */
SetAPen(rp, BLOCKPEN);
SetDrMd(rp, JAM2);
drawbit(line->ln_Line, xStart, line->ln_Strlen);
break;
case 2: /* start of line in block */
WORD block1col = vw->vw_Block[1].pos_Col;
SetAPen(rp, BLOCKPEN);
SetDrMd(rp, JAM2);
if(xStart < block1col)
drawbit(line->ln_Line, xStart, block1col + 1);
else
block1col = xStart;
SetAPen(rp, TEXTPEN);
drawbit(line->ln_Line, block1col, line->ln_Strlen);
break;
case 3: /* end of line in block */
WORD block0col = vw->vw_Block[0].pos_Col;
SetAPen(rp, TEXTPEN);
SetDrMd(rp, JAM2);
if(xStart < block0col)
drawbit(line->ln_Line, xStart, block0col + 1);
else
block0col = xStart;
SetAPen(rp, BLOCKPEN);
drawbit(line->ln_Line, block0col, line->ln_Strlen);
break;
case 4: /* middle of line in block */
WORD block0col = vw->vw_Block[0].pos_Col;
WORD block1col = vw->vw_Block[1].pos_Col;
SetAPen(rp, TEXTPEN);
SetDrMd(rp, JAM2);
if(xStart < block0col)
drawbit(line->ln_Line, xStart, block0col + 1);
else
block0col = xStart;
SetAPen(rp, BLOCKPEN);
if(block0col < block1col)
drawbit(line->ln_Line, block0col, block1col + 1);
else
block1col = block0col;
SetAPen(rp, TEXTPEN);
drawbit(line->ln_Line, block1col, line->ln_Strlen);
break;
}
}
}
VOID
redrawall(VOID)
{
VW *vw = CurrVW;
LONG linenum = vw->vw_StartLine;
LINE *line = vw->vw_Tx->tx_Lines + linenum;
WORD y = 0;
SetAPen(vw->vw_Rp, 0);
SetDrMd(vw->vw_Rp, JAM2);
RectFill(vw->vw_Rp, vw->vw_XStartPix, vw->vw_YStartPix, vw->vw_XEndPix - 1, vw->vw_YEndPix - 1);
while((y < vw->vw_MaxY) && (linenum < vw->vw_Tx->tx_NumLines))
{
pentoline(y);
drawline(line, linenum);
y++;
linenum++;
line++;
}
}
VOID
redrawallfrom(WORD col, LONG lineNum)
{
VW *vw = CurrVW;
LINE *line = vw->vw_Tx->tx_Lines + lineNum;
WORD y = lineNum - vw->vw_StartLine;
UWORD yord = (y * vw->vw_FontY) + vw->vw_YStartPix;
if(col < vw->vw_StartCol)
col = vw->vw_StartCol;
if((y >= 0) && (y < vw->vw_MaxY))
{
SetAPen(vw->vw_Rp, 0);
SetDrMd(vw->vw_Rp, JAM2);
RectFill(vw->vw_Rp, ((col - vw->vw_StartCol) * vw->vw_FontX) + vw->vw_XStartPix, yord, vw->vw_XEndPix - 1, yord + vw->vw_FontY - 1);
pentopos(col - vw->vw_StartCol, y);
drawlinepart(line, lineNum, col);
line++;
lineNum++;
y++;
yord += vw->vw_FontY;
}
else
{
y = 0;
yord = vw->vw_YStartPix;
lineNum = vw->vw_StartLine;
line = vw->vw_Tx->tx_Lines + lineNum;
}
if(y < vw->vw_MaxY)
{
SetAPen(vw->vw_Rp, 0);
SetDrMd(vw->vw_Rp, JAM2);
RectFill(vw->vw_Rp, vw->vw_XStartPix, yord, vw->vw_XEndPix - 1, vw->vw_YEndPix - 1);
while((y < vw->vw_MaxY) && (lineNum < vw->vw_Tx->tx_NumLines))
{
pentoline(y);
drawline(line, lineNum);
y++;
lineNum++;
line++;
}
}
}
VOID
redrawline(LONG lineNum)
{
VW *vw = CurrVW;
UWORD yord = ((lineNum - vw->vw_StartLine) * vw->vw_FontY) + vw->vw_YStartPix;
SetAPen(vw->vw_Rp, 0);
SetDrMd(vw->vw_Rp, JAM2);
RectFill(vw->vw_Rp, vw->vw_XStartPix, yord, vw->vw_XEndPix - 1, yord + vw->vw_FontY - 1);
pentoline(lineNum - vw->vw_StartLine);
drawline(vw->vw_Tx->tx_Lines + lineNum, lineNum);
}
VOID
redrawlinefrom(WORD col, LONG lineNum)
{
VW *vw = CurrVW;
if(col < vw->vw_StartCol)
col = vw->vw_StartCol;
if((lineNum >= vw->vw_StartLine) && (lineNum < vw->vw_StartLine + vw->vw_MaxY))
{
UWORD yord = ((lineNum - vw->vw_StartLine) * vw->vw_FontY) + vw->vw_YStartPix;
SetAPen(vw->vw_Rp, 0);
SetDrMd(vw->vw_Rp, JAM2);
RectFill(vw->vw_Rp, vw->vw_XStartPix + ((col - vw->vw_StartCol) * vw->vw_FontX), yord, vw->vw_XEndPix - 1, yord + vw->vw_FontY - 1);
pentopos(col - vw->vw_StartCol, lineNum - vw->vw_StartLine);
drawlinepart(vw->vw_Tx->tx_Lines + lineNum, lineNum, col);
}
}
/*
*/
VOID
redrawcmdline(STRPTR prompt, STRPTR cmdLine, LONG promptLen, LONG cmdLen)
{
VW *vw = CurrVW;
struct RastPort *rp = vw->vw_Rp;
WORD yclr = ((vw->vw_MaxY - 1) * vw->vw_FontY) + vw->vw_YStartPix;
SetAPen(rp, 0);
SetDrMd(rp, JAM2);
RectFill(rp, vw->vw_XStartPix, yclr, vw->vw_XEndPix - 1, yclr + vw->vw_FontY - 1);
SetAPen(rp, TEXTPEN);
Move(rp, vw->vw_XStartPix, ((vw->vw_MaxY - 1) * vw->vw_FontY) + vw->vw_FontStart);
drawbit(prompt, 0, promptLen + 1);
drawbit(cmdLine - promptLen, promptLen, cmdLen + promptLen + 1);
}
VOID
redrawcmdlinefrom(STRPTR prompt, STRPTR cmdLine, LONG promptLen, LONG cmdLen, WORD startPos)
{
VW *vw = CurrVW;
struct RastPort *rp = vw->vw_Rp;
WORD yclr = ((vw->vw_MaxY - 1) * vw->vw_FontY) + vw->vw_YStartPix;
WORD xord;
if(startPos < vw->vw_StartCol)
startPos = vw->vw_StartCol;
if(startPos < (vw->vw_StartCol + vw->vw_MaxX))
{
xord = vw->vw_XStartPix + (startPos * vw->vw_FontX);
SetAPen(rp, 0);
SetDrMd(rp, JAM2);
RectFill(rp, xord, yclr, vw->vw_XEndPix - 1, yclr + vw->vw_FontY - 1);
SetAPen(rp, TEXTPEN);
Move(rp, xord, ((vw->vw_MaxY - 1) * vw->vw_FontY) + vw->vw_FontStart);
if(startPos < promptLen)
{
drawbit(prompt, startPos, promptLen + 1);
drawbit(cmdLine - promptLen, promptLen, cmdLen + promptLen + 1);
}
else
drawbit(cmdLine - promptLen, startPos, cmdLen + promptLen + 1);
}
}
/*
* redraws the line which the command line overwrote
*/
VOID
restorecmdline(VOID)
{
VW *vw = CurrVW;
UWORD yord = ((vw->vw_MaxY - 1) * vw->vw_FontY) + vw->vw_YStartPix;
LONG linenum = vw->vw_StartLine + vw->vw_MaxY - 1;
SetAPen(vw->vw_Rp, 0);
SetDrMd(vw->vw_Rp, JAM2);
RectFill(vw->vw_Rp, vw->vw_XStartPix, yord, vw->vw_XEndPix - 1, yord + vw->vw_FontY - 1);
if(vw->vw_Tx->tx_NumLines > linenum)
{
pentoline(vw->vw_MaxY - 1);
drawline(vw->vw_Tx->tx_Lines + linenum, linenum);
}
}
/*
* draws the cursor for the command line
*/
VOID
cmdlncursor(BOOL status)
{
VW *vw = CurrVW;
struct RastPort *rp = vw->vw_Rp;
if(status)
{
SetAPen(rp, CURSPEN);
SetDrMd(rp, JAM2 | INVERSVID);
}
else
{
SetAPen(rp, TEXTPEN);
SetDrMd(rp, JAM2);
}
Move(rp, vw->vw_XStartPix + ((vw->vw_CursorPos.pos_Col - vw->vw_StartCol) * vw->vw_FontX), ((vw->vw_MaxY - 1) * vw->vw_FontY) + vw->vw_FontStart);
Text(rp, " ", 1);
}
/*
* The idea with this routine is that each function used to perform some type
* of operation OR's the refresh type that it needs into the vw_RefreshType
* flag. Then at the end of the operation the highest level routine calls
* refresh() and the smallest type of refresh possible is performed.
*
* the only problem is that most of the low level editing functions in
* edit.c don't set the refresh flag, oh well...
*/
VOID
refresh(VOID)
{
VW *vw = CurrVW;
if(vw && (!vw->vw_DeferRefresh))
{
if((!vw->vw_Sleeping) && (!vw->vw_DisplayLock))
{
WORD refflags = vw->vw_RefreshType;
if(refflags & RFF_ALL)
redrawall();
else if(refflags & RFF_ALLFROM)
{
if(vw->vw_RefreshPos.pos_Line < vw->vw_StartLine)
{
vw->vw_RefreshPos.pos_Line = vw->vw_StartLine;
vw->vw_RefreshPos.pos_Col = 0;
}
if(vw->vw_RefreshPos.pos_Line <= vw->vw_StartLine + vw->vw_MaxY)
redrawallfrom(vw->vw_RefreshPos.pos_Col, vw->vw_RefreshPos.pos_Line);
}
else if(refflags & RFF_CURSLINE)
redrawline(vw->vw_CursorPos.pos_Line);
else if(refflags & RFF_LINEFROM)
{
if((vw->vw_RefreshPos.pos_Line >= vw->vw_StartLine) && (vw->vw_RefreshPos.pos_Line <= vw->vw_StartLine + vw->vw_MaxY))
redrawlinefrom(vw->vw_RefreshPos.pos_Col, vw->vw_RefreshPos.pos_Line);
}
vw->vw_RefreshType = 0;
vw->vw_LastRefresh = vw->vw_Tx->tx_Changes;
}
}
else if(vw)
vw->vw_DeferRefresh--;
}
/*
* This must be called if you want to set the refresh position, this routine
* makes it all work :-)
*/
VOID
setrefresh(WORD refFlag, WORD refX, LONG refY)
{
VW *vw = CurrVW;
if(refFlag & (RFF_LINEFROM | RFF_ALLFROM))
{
if(vw->vw_RefreshType & (RFF_ALLFROM | RFF_LINEFROM))
{
if(vw->vw_RefreshPos.pos_Line > refY)
{
vw->vw_RefreshType |= RFF_ALLFROM;
vw->vw_RefreshPos.pos_Col = refX;
vw->vw_RefreshPos.pos_Line = refY;
}
else if((vw->vw_RefreshPos.pos_Line == refY) && (vw->vw_RefreshPos.pos_Col > refX))
{
vw->vw_RefreshType |= refFlag;
vw->vw_RefreshPos.pos_Col = refX;
}
else
vw->vw_RefreshType |= RFF_ALLFROM;
}
else
{
vw->vw_RefreshType |= refFlag;
vw->vw_RefreshPos.pos_Col = refX;
vw->vw_RefreshPos.pos_Line = refY;
}
}
else
vw->vw_RefreshType |= refFlag;
}
/*
* this function steps through all views attached to this file refresh()'ing
* each one.
*/
VOID
refreshallviews(TX *tx)
{
VW *oldvw = CurrVW;
for(CurrVW = (VW *)tx->tx_Views.mlh_Head; CurrVW->vw_Node.mln_Succ; CurrVW = (VW *)CurrVW->vw_Node.mln_Succ)
{
if(!CurrVW->vw_Sleeping)
{
cursor(OFF);
refresh();
cursor(ON);
}
}
CurrVW = oldvw;
cursor(OFF);
}